/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2009>  <Asaf Yarkoni asaf@yarkoni.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using MyPhotoIndex.Controls;
using System.Drawing;
using MyPhotoIndex.ImageBank;
using MyPhotoIndex.DataAccess;
using MyPhotoIndex.Utilities.Types;
using System.Collections.ObjectModel;
using System.Diagnostics;
using MyPhotoIndex.Interfaces;
using MyPhotoIndex.Plugins.ImageFormatProviders;
using MyPhotoIndex.Utilities;
using MyPhotoIndex.Settings;
using System.IO;
using System.Globalization;
using MyPhotoIndex.Interfaces.Imaging;
using MyPhotoIndex.Interfaces.Tagging;
using MyPhotoIndex.Interfaces.ImageFormatProviders;
using MyPhotoIndex.ImageBank.Query;
using MyPhotoIndex.MainMDI;

namespace MyPhotoIndex
{
    public partial class Main
    {
        private void rcMenuCopy_Click(object sender, EventArgs e)
        {
            StringCollection fileList = new StringCollection();
            foreach (int selectedImageId in photoThumbViewer1.SelectedImages)
            {
                fileList.Add(Storage.Instance[selectedImageId].FileName);
            }

            if (fileList.Count > 0)
            {
                Clipboard.SetFileDropList(fileList);
            }
        }

        private void rcmenuRotateLeft90_Click(object sender, EventArgs e)
        {
            ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
            RotateImages(ddi.Text, ddi.Image, photoThumbViewer1.SelectedImages, true);
        }

        private void rcmenuRotateRight90_Click(object sender, EventArgs e)
        {
            ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
            RotateImages(ddi.Text, ddi.Image, photoThumbViewer1.SelectedImages, false);
        }

        private void RotateImages(string text, Image icon, ReadOnlyCollection<int> images, bool left)
        {
            if (images.Count == 1)
            {
                RotateImage(images[0], left);
                return;
            }

            using (AsyncProgressForm progressForm = new AsyncProgressForm(this, text, icon, images.Count * 2))
            {
                List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);
                foreach (int selectedImageId in selectedImages)
                {
                    progressForm.Increment();
                    RotateImage(selectedImageId, left);
                    progressForm.Increment();
                    if (progressForm.Stop == true)
                    {
                        break;
                    }
                }
            }
        }

        private void RotateImage(int imageId, bool left)
        {
            IImageData imageData = Storage.Instance[imageId];
            lock (imageData.SyncLock)
            {
                if (imageData.CanRotate == true &&
                    imageData.LinkStatus == ImageLinkStatus.Valid)
                {
                    try
                    {
                        Thumbnail thumbnail = photoThumbViewer1.GetDrawnImage(imageData.Id);
                        if (thumbnail != null)
                        {
                            if (left == false)
                            {
                                thumbnail.RotateAnimation(0, 90);
                            }
                            else
                            {
                                thumbnail.RotateAnimation(360, 270);
                            }
                        }

                        imageData.Rotate(left ? RotateFlipType.Rotate270FlipNone : RotateFlipType.Rotate90FlipNone);
                    }
                    catch (UnauthorizedAccessException uex)
                    {
                        ApplicationAlert.Show(this, Resources.Resources.FileIsMarkedAsReadOnly, Resources.Resources.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        Logger.Log(uex);
                    }
                    catch (FileNotFoundException fex)
                    {
                        ApplicationAlert.Show(this, String.Format(Resources.Resources.TheFileWasNotDound + ":{0}", imageData.FileName));
                        Logger.Log(fex);
                    }
                    catch (Exception ex)
                    {
                        ApplicationAlert.Show(this, ex.ToString());
                        Logger.Log(ex);
                    }
                }
            }
        }

        private void RemoveItemsMenu_ItemClicked(object sender, EventArgs e)
        {
            ToolStripDropDownItem menuItem = (ToolStripDropDownItem)sender;
            int tagId = Convert.ToInt32(menuItem.Name, CultureInfo.InvariantCulture);

            ReadOnlyCollection<int> selectedImages = (ReadOnlyCollection<int>)menuItem.Tag;
            Storage.Instance.AddRemoveImageTags(selectedImages, new int[] { tagId }, false);
        }

        private void BuidMenuRemoveTagList(ToolStripMenuItem removeTagMenuItem, ReadOnlyCollection<int> selectedItems)
        {
            removeTagMenuItem.DropDown = new ToolStripDropDown();
            removeTagMenuItem.Enabled = false;

            List<int> tagList = GetImageTagList(selectedItems);
            if (tagList.Count == 0)
            {
                return;
            }

            foreach (int tagId in tagList)
            {
                IImageTag tag = myPhotoIndexImageTagTreeView1.GetTag(tagId);
                if (tag != null)
                {
                    Image menuIcon = null;
                    if (tag.Thumbnail != null)
                    {
                        try
                        {
                            menuIcon = new Bitmap(tag.Thumbnail, 32, 32);//.GetThumbnailImage(32, 32, null, IntPtr.Zero);
                        }
                        catch
                        {
                            menuIcon = new Bitmap(32, 32);
                        }
                    }
                    else
                    {
                        menuIcon = new Bitmap(32, 32);
                    }

                    String tagName = tag.Name;
                    if (tag.UniqueName == false)
                    {
                        tagName = tag.Path;
                    }

                    ToolStripMenuItem newItem = new ToolStripMenuItem(tagName, menuIcon, new EventHandler(RemoveItemsMenu_ItemClicked), tag.Id.ToString(CultureInfo.InvariantCulture));
                    newItem.ImageScaling = ToolStripItemImageScaling.None;
                    newItem.Tag = selectedItems;
                    removeTagMenuItem.DropDownItems.Add(newItem);
                }
            }

            if (removeTagMenuItem.DropDownItems.Count > 0)
            {
                removeTagMenuItem.Enabled = true;
            }
        }

        private void rcMenuPrint_Click(object sender, EventArgs e)
        {
            PrintImages(false);
        }

        private void shareToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShareImages(false);
        }

        private static List<int> GetImageTagList(ReadOnlyCollection<int> selectedImages)
        {
            List<int> tagList = new List<int>();
            foreach (int selectedImageId in selectedImages)
            {
                IImageData imageData = Storage.Instance[selectedImageId];
                foreach (int tagId in imageData.Tags)
                {
                    if (tagList.Contains(tagId) == false)
                    {
                        tagList.Add(tagId);
                    }
                }
            }

            return tagList;
        }

        private void DeletetoolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (photoThumbViewer1.SelectedImages.Count == 0)
            {
                return;
            }

            CheckBoxParameters checkBoxParameters = new CheckBoxParameters();
            checkBoxParameters.Text = Resources.Resources.DeleteFromDisk;
            DialogResult dr = ApplicationAlert.Show(Resources.Resources.DeleteImageAlert, Resources.Resources.DeleteImageAlertTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, ref checkBoxParameters);
            if (dr != DialogResult.OK)
            {
                return;
            }

            List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);
            foreach (int selectedImageId in selectedImages)
            {
                IImageData imageData = Storage.Instance[selectedImageId];
                if (imageData.VersionsCount > 0)
                {
                    dr = ApplicationAlert.Show(Resources.Resources.ImageVersionMasterDelete, Resources.Resources.DeleteImageAlertTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (dr != DialogResult.Yes)
                    {
                        return;
                    }
                    break;
                }
            }

            ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
            using (AsyncProgressForm progressForm = new AsyncProgressForm(this, ddi.Text, ddi.Image, photoThumbViewer1.SelectedImages.Count * 2))
            {
                List<int> deleteList = new List<int>(photoThumbViewer1.SelectedImages);
                int imageId = photoThumbViewer1.GetNextThumbnail(false);

                foreach (int selectedImageId in deleteList)
                {
                    progressForm.Increment();
                    IImageData imageData = Storage.Instance[selectedImageId];

                    try
                    {// refresh the selected images pane
                        m_selectedImages.Remove(imageData.Id);
                        SelectedThumbnailViewer.Refresh();

                        // delete the image from the image collection
                        imageData.Delete(checkBoxParameters.Value, ApplicationSettings.Default.SendToRecycleBin);
                    }
                    catch (UnauthorizedAccessException ex)
                    {
                        Logger.Log(ex);
                        ApplicationAlert.Show("failed to delete {0} \n Check that the file is not marked as read only");
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                    }

                    this.photoThumbViewer1.SelectImage(selectedImageId, false);
                    this.photoThumbViewer1.Refresh();
                    UpdateStatusBar();

                    progressForm.Increment();
                    if (progressForm.Stop == true)
                    {
                        break;
                    }
                }

                this.photoThumbViewer1.SelectImage(imageId, true);
                this.photoThumbViewer1.ScrollToSelected();
                BuildFolderTree();
            }
        }

        private void DatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                EditDatesForm edf = new EditDatesForm();
                edf.StartPosition = FormStartPosition.CenterParent;

                IImageData oneImageData = Storage.Instance[photoThumbViewer1.SelectedImages[0]];
                edf.DateTaken = oneImageData.DateTaken;
                edf.DateDigitized = (oneImageData.DateDigitized == DateTime.MinValue) ? edf.DateTaken : oneImageData.DateDigitized;
                DialogResult dr = edf.ShowDialog(this);
                if (dr != DialogResult.OK)
                {
                    return;
                }

                ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
                using (AsyncProgressForm progressForm = new AsyncProgressForm(this, ddi.Text, ddi.Image, photoThumbViewer1.SelectedImages.Count * 2))
                {
                    List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);
                    foreach (int selectedImageId in selectedImages)
                    {
                        progressForm.Increment();
                        IImageData imageData = Storage.Instance[selectedImageId];
                        if (imageData.LinkStatus == ImageLinkStatus.Valid)
                        {
                            try
                            {
                                imageData.DateTaken = edf.DateTaken;
                                imageData.DateDigitized = edf.DateDigitized;
                                imageData.Update(true, false);
                            }
                            catch (UnauthorizedAccessException)
                            {
                                ApplicationAlert.Show("File Is Marked as read only");
                            }
                        }

                        progressForm.Increment();
                        if (progressForm.Stop == true)
                        {
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
        }

        private void ChangeCommentStripMenuItem_Click(object sender, EventArgs e)
        {
            if (photoThumbViewer1.SelectedImages.Count == 0)
            {
                return;
            }

            EditCommentForm ecf = new EditCommentForm();
            ecf.StartPosition = FormStartPosition.CenterParent;

            IImageData oneImageData = Storage.Instance[photoThumbViewer1.SelectedImages[0]];
            ecf.Comment = oneImageData.Comment;
            DialogResult dr = ecf.ShowDialog(this);
            if (dr != DialogResult.OK)
            {
                return;
            }

            ImageBatchOperationProcessor.ProcessBatch<string>(photoThumbViewer1.SelectedImages, ecf.Text, new ProcessOneImageDelegate<string>(ImageOperations.UpdateComments), ecf.Comment);
        }

        private void UpdateThumbnailToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
            ImageBatchOperationProcessor.ProcessBatch<object>(photoThumbViewer1.SelectedImages, ddi.Text, new ProcessOneImageDelegate<object>(ImageOperations.UpdateThumbnail), null);
        }

        void updateSourceLabelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (photoThumbViewer1.SelectedImages.Count == 0)
            {
                return;
            }

            EditSourceLabelForm eslf = new EditSourceLabelForm();
            eslf.StartPosition = FormStartPosition.CenterParent;

            IImageData oneImageData = Storage.Instance[photoThumbViewer1.SelectedImages[0]];
            eslf.Label = oneImageData.SourceLabel;
            DialogResult dr = eslf.ShowDialog(this);
            if (dr != DialogResult.OK)
            {
                return;
            }

            ImageBatchOperationProcessor.ProcessBatch<string>(photoThumbViewer1.SelectedImages, eslf.Text, new ProcessOneImageDelegate<string>(ImageOperations.UpdateSourceLabel), eslf.Label);
        }

        private void OpenContainingFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Thumbnail thumbnail = imageContextMenu.Tag as Thumbnail;
            IImageData imageData = thumbnail.ImageData;

            Process.Start("explorer.exe", imageData.FileName + " ,/e, /select");
        }

        private void UnLockToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
            Thumbnail thumbnail = imageContextMenu.Tag as Thumbnail;
            IImageData imageData = thumbnail.ImageData;
            IEncryptedFormatProvider provider = imageData.FormatProvider as IEncryptedFormatProvider;
            if (provider == null)
            {
                return;
            }

            while (true)
            {
                EnterKeyForm ekf = new EnterKeyForm(false);
                DialogResult result = ekf.ShowDialog(this);
                if (result == DialogResult.Cancel)
                {
                    return;
                }

                bool valid = false;
                try
                {
                    valid = provider.ValidateKey(imageData.FileName, ekf.Key);
                }
                catch (DirectoryNotFoundException dex)
                {
                    imageData.LinkStatus = ImageLinkStatus.Invalid;
                    Logger.Log(dex);
                }
                catch (FileNotFoundException fex)
                {
                    imageData.LinkStatus = ImageLinkStatus.Invalid;
                    Logger.Log(fex);
                }

                if (valid == true)
                {
                    provider.AddKey(ekf.Key);
                    break;
                }
            }

            UpdateMenuItemsStatus();
            Storage.Instance.RefreshCache();
            photoThumbViewer1.Refresh();
        }

        private void EncryptToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EnterKeyForm ekf = new EnterKeyForm(true);
            DialogResult result = ekf.ShowDialog(this);
            if (result == DialogResult.Cancel)
            {
                return;
            }

            ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
            IEncryptedFormatProvider provider = ImageFormatProviders.Default["mei"] as IEncryptedFormatProvider;
            if (provider == null)
            {
                return;
            }

            using (AsyncProgressForm progressForm = new AsyncProgressForm(this, ddi.Text, ddi.Image, photoThumbViewer1.SelectedImages.Count * 2))
            {
                List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);
                foreach (int selectedImageId in selectedImages)
                {
                    progressForm.Increment();
                    IImageData imageData = Storage.Instance[selectedImageId];

                    if (imageData.FormatProvider.CanSave == true &&
                        imageData.Encrypted == false)
                    {
                        try
                        {
                            provider.Encrypt(imageData, ekf.Key);
                            imageData.Update(false, true);
                        }
                        catch (Exception ex)
                        {
                            ApplicationAlert.Show(ex.Message);
                        }
                    }

                    progressForm.Increment();
                    if (progressForm.Stop == true)
                    {
                        break;
                    }
                }
            }

            Storage.Instance.RefreshCache();
            photoThumbViewer1.Refresh();
            UpdateMenuItemsStatus();
        }

        private void DecryptToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripDropDownItem ddi = (ToolStripDropDownItem)sender;
            List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);

            ApplicationContext.Instance.ProcessProgress.Maximum = (selectedImages.Count * 2);
            ApplicationContext.Instance.ProcessProgress.IsInfinite = false;
            ApplicationContext.Instance.ProcessProgress.Running = true;

            foreach (int selectedImageId in selectedImages)
            {
                ApplicationContext.Instance.ProcessProgress.Value++;
                IImageData imageData = Storage.Instance[selectedImageId];

                if (imageData.Encrypted == true)
                {
                    IEncryptedFormatProvider provider = null;

                    try
                    {
                        provider = imageData.FormatProvider as IEncryptedFormatProvider;
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                        continue;
                    }

                    try
                    {
                        if (provider.Decrypt(imageData) == false)
                        {
                            while (true)
                            {
                                EnterKeyForm ekf = new EnterKeyForm(false);
                                DialogResult result = ekf.ShowDialog(this);
                                if (result == DialogResult.Cancel)
                                {
                                    ApplicationContext.Instance.ProcessProgress.Running = false;
                                    return;
                                }

                                provider.AddKey(ekf.Key);

                                if (TryDecrypt(provider, imageData) == true)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                    }

                    imageData.Update(false, true);
                }

                Application.DoEvents();
                ApplicationContext.Instance.ProcessProgress.Value++;

                //if (progressForm.Stop == true)
                //{
                //    break;
                //}
            }

            ApplicationContext.Instance.ProcessProgress.Running = false;

            Storage.Instance.RefreshCache();
            photoThumbViewer1.Refresh();
            UpdateMenuItemsStatus();
        }

        private bool TryDecrypt(IEncryptedFormatProvider provider, IImageData imageData)
        {
            try
            {
                return provider.Decrypt(imageData);
            }
            catch (ImageEncryptedException)
            {
            }

            return false;
        }

        void SetAsWpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (photoThumbViewer1.SelectedImages.Count == 0)
            {
                return;
            }

            DesktopWallpaperSetter wps = new DesktopWallpaperSetter();
            List<IImageData> imageList = new List<IImageData>();

            List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);
            foreach (int selectedImageId in selectedImages)
            {
                IImageData imageData = Storage.Instance[selectedImageId];
                imageList.Add(imageData);
            }

            wps.SetWallpaper(imageList, DesktopWallpaperSetter.Style.Centered);
        }

        void ImageVersionsShowAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int imageId = this.photoThumbViewer1.SelectedImages[0];
            ShowImageVersions(imageId);

            UpdateMenuItemsStatus();
        }

        private void ShowImageVersions(int imageId)
        {
            IImageData imageData = Storage.Instance[imageId];
            if (imageData != null &&
                imageData.VersionsCount > 0)
            {
                List<QueryParameter> queryParams = new List<QueryParameter>();
                ImageVersionParentIdQueryparameter versionParentParameter = new ImageVersionParentIdQueryparameter(imageData.Id);
                versionParentParameter.Relation = QueryParameterRelation.Or;

                queryParams.Add(versionParentParameter);
                queryParams.Add(new ImageIdQueryparameter(imageData.Id));
                QueryBuilder qb = new QueryBuilder(queryParams.ToArray(), new QueryHelper(Storage.Instance.UnFiltered), false);
                Dictionary<int, IImageData> result = qb.RunQuery();

                List<int> imageList = new List<int>(result.Keys);
                Storage.Instance.Filter(imageList);
            }
        }

        void imageVersionsSetAsPrimaryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int imageId = this.photoThumbViewer1.SelectedImages[0];
            IImageData imageData = Storage.Instance[imageId];
            if (imageData != null &&
                imageData.VersionParentId > -1)
            {
                Storage.Instance.SetAsPrimaryInVersion(imageData);
            }

            UpdateMenuItemsStatus();
        }

        void moveToFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.RootFolder = Environment.SpecialFolder.Desktop;
            if (string.IsNullOrEmpty(ApplicationSettings.Default.LastMoveToPath) == true)
            {
                folderBrowserDialog1.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            }
            else
            {
                folderBrowserDialog1.SelectedPath = ApplicationSettings.Default.LastMoveToPath;
            }

            DialogResult dr = folderBrowserDialog1.ShowDialog();

            if (dr != DialogResult.OK)
            {
                return;
            }

            ApplicationSettings.Default.LastMoveToPath = folderBrowserDialog1.SelectedPath;
            ApplicationSettings.Default.Save();

            ImageBatchOperationProcessor.ProcessBatch<string>(photoThumbViewer1.SelectedImages, moveToFolderToolStripMenuItem.Text, new ProcessOneImageDelegate<string>(ImageOperations.MoveImage), folderBrowserDialog1.SelectedPath, new ProcessOneImageDelegateError<string>(HandleImageMoveError));

            BuildFolderTree();
            Storage.Instance.ScanDiskForChanges();
        }

        void createVersionSetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);

            List<IImageData> imageList = new List<IImageData>();
            foreach (int selectedImageId in selectedImages)
            {
                IImageData imageData = Storage.Instance[selectedImageId];
                imageList.Add(imageData);
            }

            Storage.Instance.CreateNewVersionSet(imageList.ToArray());

            int versionSetParentId = -1;
            foreach (IImageData imageData in imageList)
            {
                if (imageData.VersionParentId > 0)
                {
                    versionSetParentId = imageData.VersionParentId;
                    break;
                }
                else
                    if (imageData.VersionsCount > 0)
                    {
                        versionSetParentId = imageData.Id;
                        break;
                    }
            }

            ShowImageVersions(versionSetParentId);
            myPhotoIndexImageTagTreeView1.UncheckAll();

            UpdateMenuItemsStatus();
        }

        void breakVersionSetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<int> selectedImages = new List<int>(photoThumbViewer1.SelectedImages);

            List<IImageData> imageList = new List<IImageData>();
            foreach (int selectedImageId in selectedImages)
            {
                IImageData imageData = Storage.Instance[selectedImageId];
                imageList.Add(imageData);
            }

            int versionSetParentId = -1;
            foreach (IImageData imageData in imageList)
            {
                if (imageData.VersionParentId > 0)
                {
                    versionSetParentId = imageData.VersionParentId;
                    break;
                }
                else
                    if (imageData.VersionsCount > 0)
                    {
                        versionSetParentId = imageData.Id;
                        break;
                    }
            }

            Storage.Instance.BreakVersionSet(imageList.ToArray());

            if (versionSetParentId > -1)
            {
                IImageData parent = Storage.Instance.UnFiltered[versionSetParentId];
                if (parent != null &&
                    parent.VersionsCount > 0)
                {
                    ShowImageVersions(versionSetParentId);
                    myPhotoIndexImageTagTreeView1.UncheckAll();
                }
                else
                {
                    ClearFilter();
                }
            }
            else
            {
                ClearFilter();
            }

            UpdateMenuItemsStatus();
        }

        private bool HandleImageMoveError(IImageData imageData, string state, Exception ex)
        {
            return true;
        }
    }
}
